package client

import (
	"encoding/json"
	"errors"
	"fmt"
	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
	"likeadmin/admin/schemas/req"
	"likeadmin/admin/schemas/resp"
	"likeadmin/config"
	"likeadmin/core/request"
	"likeadmin/core/response"
	"likeadmin/model/client"
	"likeadmin/util"
	"log"
	"time"
)

type IAccountService interface {
	List(c *gin.Context, page request.PageReq, listReq req.AccountListReq) (res response.PageResp, e error)
	Detail(id string) (res resp.AccountResp, e error)
	Add(c *gin.Context, addReq req.AccountAddReq) (e error)
	Edit(editReq req.AccountEditReq) (e error)
	Del(id string) (e error)
	BearerToken(tokenReq req.AccountBearerTokenReq) (e error)
	OppoAdData(id string) (e error)
	Statistic(adminId uint, listReq req.AccountListReq) (res map[string]any, e error)
}

// NewAccountService 初始化
func NewAccountService(db *gorm.DB) IAccountService {
	return &accountService{db: db}
}

// accountService 广告账户信息服务实现类
type accountService struct {
	db *gorm.DB
}

// List 广告账户信息列表
func (srv accountService) List(c *gin.Context, page request.PageReq, listReq req.AccountListReq) (res response.PageResp, e error) {
	// 分页信息
	limit := page.PageSize
	offset := page.PageSize * (page.PageNo - 1)
	// 查询
	model := srv.db.Model(&client.Account{})

	adminId := config.AdminConfig.GetAdminId(c)
	if adminId != 1 {
		model = model.Where("creater_id = ?", adminId)
	}

	if listReq.AccountId != "" {
		model = model.Where("account_id = ?", listReq.AccountId)
	}

	if listReq.Channel >= 0 {
		model = model.Where("channel = ?", listReq.Channel)
	}

	if listReq.AccountNumber != "" {
		model = model.Where("account_number like ?", "%"+listReq.AccountNumber+"%")
	}

	if listReq.AccountTitle != "" {
		model = model.Where("account_title like ?", "%"+listReq.AccountTitle+"%")
	}

	if listReq.Status >= 0 {
		model = model.Where("status = ?", listReq.Status)
	}
	if listReq.PackageName != "" {
		model = model.Where("package_name = ?", listReq.PackageName)
	}
	// 总数
	var count int64
	err := model.Count(&count).Error
	if e = response.CheckErr(err, "List Count err"); e != nil {
		return
	}
	// 数据
	var objs []client.Account
	err = model.Limit(limit).Offset(offset).Order("create_time desc").Find(&objs).Error
	if e = response.CheckErr(err, "List Find err"); e != nil {
		return
	}
	resps := []resp.AccountResp{}

	response.Copy(&resps, objs)

	bearerTokenUrl := ""
	bearerTokenCallBackUrl := "https://drama.eeopn.com/api/client/account/bearer_token"

	for i, i2 := range resps {
		// 应用渠道: 1=头条, 2=百度, 3=uc, 4=oppo, 5=vivo, 6=快手
		if i2.Channel != 1 {
			continue
		}

		//if i2.AccessTokenTime <= 0 {
		bearerTokenUrl = fmt.Sprintf("https://open.oceanengine.com/audit/oauth.html?app_id=%s&state=%s&material_auth=1&redirect_uri=%s", i2.UserAccount, i2.AccountId, bearerTokenCallBackUrl)
		resps[i].BearerTokenUrl = bearerTokenUrl
		//}

	}
	return response.PageResp{
		PageNo:   page.PageNo,
		PageSize: page.PageSize,
		Count:    count,
		Lists:    resps,
	}, nil
}

// Detail 广告账户信息详情
func (srv accountService) Detail(id string) (res resp.AccountResp, e error) {
	var obj client.Account
	err := srv.db.Where("account_id = ?", id).Limit(1).First(&obj).Error
	if e = response.CheckErrDBNotRecord(err, "数据不存在!"); e != nil {
		return
	}
	if e = response.CheckErr(err, "Detail First err"); e != nil {
		return
	}
	response.Copy(&res, obj)

	var huichuanRate resp.HuichuanRate
	if obj.HuichuanRate != "" {
		err = json.Unmarshal([]byte(obj.HuichuanRate), &huichuanRate)
		if err != nil {
			// 处理 JSON 解析错误
			log.Printf("Failed to parse HuichuanRate JSON: %v", err)
		}
		res.HuichuanRate = huichuanRate
	}

	return
}

// Add 广告账户信息新增
func (srv accountService) Add(c *gin.Context, addReq req.AccountAddReq) (e error) {
	var obj client.Account
	response.Copy(&obj, addReq)

	jsonBytes, err := json.Marshal(addReq.HuichuanRate)
	if err != nil {
		// 处理错误
		log.Printf("Failed to marshal HuichuanRate to JSON: %v", err)
		return
	}

	obj.HuichuanRate = string(jsonBytes)
	obj.AccountId = util.UitlSnow.SnowId()
	obj.CreaterID = config.AdminConfig.GetAdminId(c)

	err = srv.db.Model(client.Account{}).Create(&obj).Error
	e = response.CheckErr(err, "Add Create err")
	return
}

// Edit 广告账户信息编辑
func (srv accountService) Edit(editReq req.AccountEditReq) (e error) {
	var obj client.Account
	err := srv.db.Where("account_id = ?", editReq.AccountId).Limit(1).First(&obj).Error
	// 校验
	if e = response.CheckErrDBNotRecord(err, "数据不存在!"); e != nil {
		return
	}
	if e = response.CheckErr(err, "Edit First err"); e != nil {
		return
	}

	if obj.PackageName != editReq.PackageName {
		// 更新
		_ = srv.db.Model(client.Source{}).Where("account_id = ?", obj.AccountId).Select(
			"package_name",
		).Updates(client.Source{
			PackageName: editReq.PackageName,
		}).Error
	}

	// 更新
	response.Copy(&obj, editReq)

	jsonBytes, err := json.Marshal(editReq.HuichuanRate)
	if err != nil {
		// 处理错误
		log.Printf("Failed to marshal HuichuanRate to JSON: %v", err)
		return
	}

	obj.HuichuanRate = string(jsonBytes)

	err = srv.db.Model(client.Account{}).Where("account_id = ?", obj.AccountId).Updates(obj).Error
	e = response.CheckErr(err, "Edit Updates err")

	return
}

// Del 广告账户信息删除
func (srv accountService) Del(id string) (e error) {
	var obj client.Account
	err := srv.db.Where("account_id = ?", id).Limit(1).First(&obj).Error
	// 校验
	if e = response.CheckErrDBNotRecord(err, "数据不存在!"); e != nil {
		return
	}
	if e = response.CheckErr(err, "Del First err"); e != nil {
		return
	}
	// 删除
	err = srv.db.Model(client.Account{}).Where("account_id = ?", obj.AccountId).Delete(obj).Error
	e = response.CheckErr(err, "Del Delete err")
	return
}

// BearerToken
func (srv accountService) BearerToken(tokenReq req.AccountBearerTokenReq) (e error) {
	var obj client.Account
	err := srv.db.Model(&client.Account{}).Where("account_id = ?", tokenReq.State).Limit(1).First(&obj).Error
	// 校验
	if e = response.CheckErrDBNotRecord(err, "数据不存在!"); e != nil {
		return
	}

	if e = response.CheckErr(err, "BearerToken First err"); e != nil {
		return
	}

	resp, err := util.OceanengineCallbackUtil{}.GetAccessToken(tokenReq.AuthCode, obj.UserAccount, obj.ButlerAccount)
	log.Printf("BearerToken: result=%+v", resp)

	if err != nil {
		e = response.CheckErr(err, "获取access_token失败")
		return
	}

	// 检查响应是否包含必要字段
	if resp == nil {
		e = response.CheckErr(errors.New("empty response"), "获取access_token失败")
		return
	}

	// 检查code是否为0表示成功
	if code, ok := resp["code"].(float64); !ok || code != 0 {
		e = response.CheckErr(fmt.Errorf("获取access_token失败，错误码: %v", code), "获取access_token失败")
		return
	}

	// 检查data是否存在
	data, ok := resp["data"].(map[string]interface{})
	if !ok {
		e = response.CheckErr(errors.New("invalid data format"), "获取access_token失败")
		return
	}

	// 获取access_token
	if accessToken, ok := data["access_token"].(string); ok && accessToken != "" {
		// 获取refresh_token
		refreshToken := ""
		if rt, ok := data["refresh_token"].(string); ok {
			refreshToken = rt
		}

		// 获取过期时间
		expiresIn := int64(86400) // 默认24小时
		if exp, ok := data["expires_in"].(float64); ok {
			expiresIn = int64(exp)
		}

		err = srv.db.Model(client.Account{}).Where("user_account = ? AND butler_account = ? AND company_name = ?", obj.UserAccount, obj.ButlerAccount, obj.CompanyName).Updates(client.Account{
			AccessToken:      accessToken,
			RefreshToken:     refreshToken,
			AccessTokenTime:  time.Now().Unix() + expiresIn - 3600, // 提前1小时刷新
			RefreshTokenTime: time.Now().Unix() + expiresIn - 3600,
		}).Error
		e = response.CheckErr(err, "BearerToken Updates err")
	} else {
		e = response.CheckErr(errors.New("access_token为空"), "获取access_token失败")
	}

	return
}

func (srv accountService) OppoAdData(id string) (e error) {
	var obj client.Account
	err := srv.db.Model(&client.Account{}).Where("account_id = ?", id).Limit(1).First(&obj).Error
	// 校验
	if e = response.CheckErrDBNotRecord(err, "数据不存在!"); e != nil {
		return
	}

	if e = response.CheckErr(err, "BearerToken First err"); e != nil {
		return
	}

	toDay := time.Now().Format("20060102")

	resp, err := util.OppoCallbackUtil{}.AdData(obj, toDay, "DAY")

	if err != nil {
		e = response.CheckErr(err, "获取oppo成本失败")
		return
	}

	fmt.Println("oppo成本:", fmt.Sprintf("获取oppo成本:%v", resp))

	return
}

func (srv accountService) Statistic(adminId uint, listReq req.AccountListReq) (res map[string]any, e error) {

	statistic := map[string]any{
		"cost":     0,
		"recharge": 0,
		"users":    0,
	}

	// 查询
	model := srv.db.Model(&client.Account{})
	if adminId != 1 {
		model.Where("creater_id = ?", adminId)
	}
	if listReq.Channel >= 0 {
		model = model.Where("channel = ?", listReq.Channel)
	}
	if listReq.AccountNumber != "" {
		model = model.Where("account_number like ?", "%"+listReq.AccountNumber+"%")
	}

	if listReq.AccountTitle != "" {
		model = model.Where("account_title like ?", "%"+listReq.AccountTitle+"%")
	}

	if listReq.Status >= 0 {
		model = model.Where("status = ?", listReq.Status)
	}
	if listReq.PackageName != "" {
		model = model.Where("package_name = ?", listReq.PackageName)
	}

	model = model.Where("delete_time = ?", 0)

	// 成本
	var totalCost uint
	_ = model.Select("IFNULL(SUM(cost),0)").Scan(&totalCost).Error

	// 成本
	var totalRecharge uint
	_ = model.Select("IFNULL(SUM(recharge),0)").Scan(&totalRecharge).Error

	// 成本
	var totalUsers uint
	_ = model.Select("IFNULL(SUM(users),0)").Scan(&totalUsers).Error

	// 转换为元并保留两位小数
	costFloat := float64(totalCost) / 100.0
	rechargeFloat := float64(totalRecharge) / 100.0

	statistic["cost"] = fmt.Sprintf("%.2f", costFloat)
	statistic["recharge"] = fmt.Sprintf("%.2f", rechargeFloat)

	statistic["users"] = totalUsers

	return statistic, e
}
